<?php
namespace Pub\wx;
defined('IN_IA') or exit('Access Denied');
use Pub\tool\Tool;

class WxPay extends Wx
{
    private $_payment = array();  //支付相关数据
    private $_account = '';  //商户账号
    private $_key = '';  //商户密钥
    protected $_cert_cert = '';   //商户证书cert
    protected $_cert_key = '';  //商户证书key
    private $_order_id = '';  //订单id
    private $_prepay_id = '';  //微信下单返回prepay_id
    private $_cert_dir = "";

    public function __construct($_order_id = '')
    {
        global $_W;
        parent::__construct();
        $_setting = uni_setting();
        $this->_payment = $_setting["payment"];
        $this->_account = $_setting["payment"]["wechat"]["mchid"];
        $this->_key = $_setting["payment"]["wechat"]["apikey"];
        $this->_cert_cert = "";
        $this->_cert_key = "";
        $this->_order_id = $_order_id;
    }

    /**
     * 微信统一下单
     * @param $_openid 用户的openid
     * @param $_money 订单金额
     * @param $_body 下单的商品描述
     * @return array
     */
    public function createOrder($_openid,$_money,$_body)
    {
        global $_W;
        $_data['appid'] = $this->_appid;
        $_data['mch_id'] = $this->_account;
        $_data['nonce_str'] = Tool::createCode();
        $_data['body'] = $_body;
        $_data['out_trade_no'] = $this->_order_id;
        $_data['total_fee'] = $_money * 100;
        $_data['spbill_create_ip'] = CLIENT_IP;
        $_data['notify_url'] = $_W['siteroot'].'addons/kuyuan_red/notify.php';
        $_data['trade_type'] = 'JSAPI';
        $_data['openid'] = $_openid;
        $_data['sign'] = $this->sign($_data);
        $_xml = array2xml($_data);
        $_return = $this->wxHttpsRequestPem('https://api.mch.weixin.qq.com/pay/unifiedorder',$_xml);
        $_return = xml2array($_return);
        if($_return['result_code'] == 'SUCCESS' && $_return['return_code'] == 'SUCCESS'){
            $this->_prepay_id = $_return['prepay_id'];
            return array('status'=>'success','prepay_id'=>$this->_prepay_id);
        }else{
            return array('status'=>'error','err_msg'=>$_return['err_code_des'] ? $_return['err_code_des'] : $_return["return_msg"]);
        }
    }

    /**
     * JS支付，小程序支付获取支付参数
     * @param unknown prepay_id
     * @return string|unknown
     */
    public function jsPayParam(){
        $_data['appId'] = $this->_appid;
        $_data['timeStamp'] = ''.TIMESTAMP;
        $_data['nonceStr'] = Tool::createCode();
        $_data['package'] = 'prepay_id='.$this->_prepay_id;
        $_data['signType'] = 'MD5';
        $_data['paySign'] = $this->sign($_data);
        return $_data;
    }

    /**
     * 订单退款
     * @param string $_refundOrder  退款的订单号
     * @param string $_order_fee   订单金额
     * @param string $_refund_fee  退款金额
     * @param string string $_description  说明
     * @throws Exception
     * @return array 返回内容
     */
    public function refund($_refundOrder,$_order_fee,$_refund_fee,$_description='')
    {
        $this->getCertKey();
        $_data['appid'] = $this->_appid;
        $_data['mch_id'] = $this->_account;
        $_data['nonce_str'] = Tool::createCode();
        $_data['out_trade_no'] = $this->_order_id;
        $_data['out_refund_no'] = $_refundOrder;
        $_data['total_fee'] = $_order_fee*100;
        $_data['refund_fee'] = $_refund_fee*100;
        if(!empty($_description)) $_data['refund_desc'] = $_description;
        $_data['sign'] = $this->sign($_data);
        $_xml = array2xml($_data);
        $_return = $this->wxHttpsRequestPem('https://api.mch.weixin.qq.com/secapi/pay/refund',$_xml,true);
        $_return = xml2array($_return);
        rmdirs($this->_cert_dir);
        if($_return['result_code'] == 'SUCCESS' && $_return['return_code'] == 'SUCCESS'){
            return array('status'=>'success');
        }else{
            $_err_msg = ($_return['err_code_des']) ? $_return['err_code_des'] : $_return['return_msg'];
            return array('status'=>'error','err_msg'=>$_err_msg);
        }
    }

    /**
     * 企业付款给用户
     * @param string $_openid 付款给用户的openid
     * @param string $_money  付款金额
     * @param string $_remark   备注
     * @return bool|DOMDocument|mixed  返回企业付款微信订单号
     * @throws Exception
     */
    public function payer($_openid,$_money,$_remark)
    {
        $this->getCertKey();
        $_data['mch_appid'] = $this->_appid;
        $_data['mchid'] = $this->_account;
        $_data['nonce_str'] = Tool::createCode();
        $_data['partner_trade_no'] = $this->_order_id;
        $_data['openid'] = $_openid;
        $_data['check_name'] = 'NO_CHECK';
        $_data['amount'] = $_money*100;
        $_data['desc'] = $_remark;
        $_data['spbill_create_ip'] = CLIENT_IP;
        $_data['sign'] = $this->sign($_data);
        $_xml = array2xml($_data);
        $_return = $this->wxHttpsRequestPem('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers',$_xml,true);
        $_return = xml2array($_return);
        rmdirs($this->_cert_dir);
        if($_return['result_code'] == 'SUCCESS' && $_return['return_code'] == 'SUCCESS'){
            return array('status'=>'success','data'=>$_return['payment_no']);
        }else{
            $_err_msg = ($_return['err_code_des']) ? $_return['err_code_des'] : $_return['return_msg'];
            return array('status'=>'error','err_msg'=>$_err_msg);
        }
    }

    /**
     * 获取证书
     */
    private function getCertKey()
    {
        global $_W;
        $this->_cert_dir = ATTACHMENT_ROOT.KUYUAN_MODEL_NAME."/".$_W["account"]["uniacid"]."/wx_cert/";
        $_dir = $this->_cert_dir."/".TIMESTAMP.'/';
        load()->func('file');
        mkdirs($_dir);
        $this->_cert_cert = $_dir."louie_cert.pem";
        $this->_cert_key = $_dir."louie_key.pem";
        $_cert = authcode($this->_payment["wechat_refund"]["cert"],"DECODE");
        $_key = authcode($this->_payment["wechat_refund"]["key"],"DECODE");
        file_put_contents($this->_cert_cert,$_cert);
        file_put_contents($this->_cert_key,$_key);
    }

    /**
     * 获取sign
     * @param unknown $_data
     * @return string
     */
    private function sign($_data){
        ksort($_data);
        $_stringA = '';
        foreach($_data as $_key=>$_value){
            $_stringA .= $_key.'='.$_value.'&';
        }
        $_string = $_stringA.'key='.$this->_key;
        return strtoupper(md5($_string));
    }

    public function __set($name, $value)
    {
        $this->$name = $value;
    }
}